from aiogram import Router, F, exceptions
from aiogram import types
from aiogram.fsm.context import FSMContext
from aiogram.utils.markdown import hbold, hlink, hitalic

import config
from keyboards import menu_keys
from keyboards.callbacks_data import MenuCategory

from loader import logger, bot, db, scheduler
from utils import RequireChannelsStates

router = Router()
router.message.filter(F.chat.type == "private")


@router.callback_query(
    MenuCategory.filter(F.category == 'require_channels'),
    MenuCategory.filter(F.action.in_({'add', 'delete'})),
    MenuCategory.filter(F.level == 4)
)
async def add_del_words(call: types.CallbackQuery, callback_data: MenuCategory, context: dict, state: FSMContext):
    if callback_data.action == 'add':
        db.add_require_channel(call.from_user.id, callback_data.chat_id, callback_data.req_channel_id)
    elif callback_data.action == 'delete':
        db.delete_require_channel(call.from_user.id, callback_data.chat_id, callback_data.req_channel_id)
    context['users'] = db.get_all_clients()
    await show_menu(call, MenuCategory(level=2, category='require_channels', chat_id=callback_data.chat_id), state)


@router.callback_query(
    MenuCategory.filter(F.category == 'require_channels'),
    MenuCategory.filter(F.action.in_({'add', 'delete'})),
)
async def add_del_words(call: types.CallbackQuery, callback_data: MenuCategory, context: dict, state: FSMContext):
    if callback_data.action == 'add':
        await show_menu(call,
                        MenuCategory(level=3, category='require_channels', action='add', chat_id=callback_data.chat_id),
                        state)
        await state.set_state(RequireChannelsStates.add)
        await state.update_data(chat_id=callback_data.chat_id)
        await state.update_data(action='add')
    elif callback_data.action == 'delete':
        await show_menu(call, MenuCategory(level=3, category='require_channels', action='delete',
                                           chat_id=callback_data.chat_id), state)


@router.callback_query(
    MenuCategory.filter(F.category == 'require_channels'),
    MenuCategory.filter(F.level <= 5),

)
async def show_menu(call: types.CallbackQuery, callback_data: MenuCategory, state: FSMContext):
    # logger.debug(callback_data)
    current_level = callback_data.level
    chats = None
    if callback_data.action == 'back':
        current_level -= 1

    if current_level == 2:
        chats_from_db = db.select_channels_by_chat(call.from_user.id, callback_data.chat_id, 'list')
        entities = []
        for c in chats_from_db:
            try:
                e = await bot.get_chat(c)
                entities.append(e)
            except exceptions.TelegramBadRequest:
                continue
            except exceptions.TelegramForbiddenError:
                continue
                # db.delete_channel(call.from_user.id, )

        chats = '\n'.join([f"⚡️ {hlink(e.title, e.invite_link)}" for e in entities]) if entities else None
    chats_text = f'Уже привязаные чаты/калалы к этому чату:\n{chats}' if chats else hitalic(
        'Привязанных каналов ещё нет\n')

    levels = {
        0: menu_keys.admin_menu() if call.from_user.id in config.ADMIN_ID else menu_keys.client_menu(),
        1: await menu_keys.list_groups_buttons(call.from_user.id),
        2: menu_keys.action(3, 'require_channels', callback_data.chat_id),
        3: menu_keys.back(1, 'require_channels')
    }
    texts = {
        0: "Вот чем вы можете управлять:",
        1: f"{hbold('Выбери чат из списка:')} \n\n"
           "Если ты не видишь нужный чат в списке - скорее всего бот там не администратор.",
        2: f"{chats_text}\nДоступны такие действия: \n",
        3: f"Видимо что-то пошло не так"
    }
    if callback_data.action == 'add':
        texts[3] = 'Здесь список всех чатов и каналов куда вы добавили бота. \n' \
                   'Выберите чат/канал для добавления как обязательный к подписке:'
        levels[3] = await menu_keys.list_channels_buttons(4, call.from_user.id, callback_data.chat_id, action='add')
    elif callback_data.action == 'delete':
        texts[3] = 'Выберите чат для удаления:'
        levels[3] = await menu_keys.list_channels_buttons(4, call.from_user.id, callback_data.chat_id, action='delete')

    await call.message.edit_text(texts[current_level], disable_web_page_preview=True)
    await call.message.edit_reply_markup(levels[current_level])
